package com.gt.web.srv.interceptors;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.gt.web.srv.annotation.login.CheckShare;
import com.gt.web.srv.annotation.login.NoAuthorization;
import com.gt.web.srv.utils.JwtUtils;
import com.gt.web.srv.utils.OptUtil;
import com.gt.web.srv.utils.RequestUtil;
import com.gt.web.srv.web.api.resource.dto.TokenDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 请求公用拦截器
 */
@Component
@Slf4j
public class CommonInterceptor implements HandlerInterceptor {

    // @Resource
    // private RedisClient redisClient;

    /*
     * 进入controller层之前拦截请求
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String traceId = RequestUtil.getTraceId(request);
        if (CharSequenceUtil.isNotBlank(traceId)) {
            log.info("traceId: {}", traceId);
        }
        HttpServletRequest httpServletRequest = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder
                .getRequestAttributes())).getRequest();
        // 1、获取 token 并处理
        String token = httpServletRequest.getHeader("token");
        // 对于特殊请求放行不拦截元象接口  直接在aop处进行sign拦截
        if (((HandlerMethod) handler).hasMethodAnnotation(CheckShare.class) && CharSequenceUtil.isBlank(token)) {
            return true;
        }
        // 非特殊请求进行判断用户名  不能为空（）
        OptUtil.ifThrow(!((HandlerMethod) handler).hasMethodAnnotation(NoAuthorization.class) && StrUtil.isBlank(token), "请提供访问令牌!");

        TokenDto jwtUserTokenBean = null;
        if (StrUtil.isNotBlank(token)) {
            jwtUserTokenBean = JwtUtils.checkToken(token, TokenDto.class);
            OptUtil.ifThrow((ObjectUtil.isNull(jwtUserTokenBean)  || StrUtil.isBlank(jwtUserTokenBean.getOpenId())), "无效令牌信息!");

        }
        // 非特殊请求进行判断用户名  不能为空（）
        if (!((HandlerMethod) handler).hasMethodAnnotation(NoAuthorization.class)) {
            OptUtil.ifThrow(ObjectUtil.isNull(jwtUserTokenBean), "无效令牌信息!");
            //OptUtil.ifThrow(StrUtil.isBlank(jwtUserTokenBean.getUserName()), RespEnum.RESPONSE_CODE_NO_PERMISSION.getCode(), RespEnum.RESPONSE_CODE_USER_ERROR.getDesc());
        }
        // 用户信息透传
        // pushUserInfoBody(request, (HandlerMethod) handler, jwtUserTokenBean);
        if (ObjectUtil.isNotNull(jwtUserTokenBean) && StrUtil.isNotBlank(jwtUserTokenBean.getOpenId())) {
            AuthUserContext.set(jwtUserTokenBean);
        }
        return true;
    }

    /*
     * 视图渲染之后的操作
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) {
        AuthUserContext.clean();
    }

    /*
     * 处理请求完成后视图渲染之前的处理操作
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) {

    }
}
